package com.platform.core.service;

import com.querydsl.core.types.Predicate;
import com.platform.comm.web.results.TreeNode;
import com.platform.core.entity.SysDepart;
import com.platform.dto.DepartNode;
import com.platform.dto.DepartQo;
import com.platform.dto.DomainTreeNode;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.MultiValueMap;

import java.util.List;
import java.util.Map;

import static com.platform.comm.constants.GlobalConstant.BASE_REDIS_CACHE_PREFIX;

/**
 * Description: 部门信息-Service接口
 *
 * @author libin Created on 2019/7/18
 **/
public interface SysDepartService extends BaseEntityBiz<SysDepart> {

    String ROOT_CODE =  "pre_ncloud_sys_depart_10000";
    String REDIS_DEPART_CODE_SEQUENCE = BASE_REDIS_CACHE_PREFIX + "depart:sequence";

    /**
     * 创建
     *
     * @param departQo 部门信息
     * @return DepartQo
     */
    DepartQo create(DepartQo departQo);

    /**
     * 修改 (编码和名称修改时，会涉及到子节点)
     *
     * @param departQo 部门信息
     * @return DepartQo
     */
    DepartQo modify(DepartQo departQo);

    /**
     * 分页查询
     *
     * @param predicate    查询条件
     * @param pageable     分页参数
     * @param parameters   查询参数
     * @param accessSubOrg accessSubOrg
     * @return 列表
     */
    Page<DepartQo> queryDeparts(Predicate predicate, Pageable pageable, MultiValueMap<String, String> parameters, String accessSubOrg);

    /**
     * 分页查询,仅供资源目录分配机构使用
     *
     * @param pageable   分页参数
     * @param parameters 查询参数
     * @return page
     */
    Page<DepartQo> queryDeparts(Map<String, String> parameters, Pageable pageable);

    /**
     * 检查统一社会信用代码
     *
     * @param id          ID（修改时用）
     * @param unifiedCode 统一社会信用代码
     * @return Long
     */
    long checkUnifiedCode(String id, String unifiedCode);

    /**
     * 检查部门编码
     *
     * @param id      ID（修改时用）
     * @param bizCode 部门编码
     * @return long
     */
    long checkAreaCode(String id, String bizCode);

    /**
     * 检查部门名称
     *
     * @param parentId   父部门名称
     * @param id         ID（修改时用）
     * @param departName 部门编码
     * @return long
     */
    long checkDepartName(String parentId, String id, String departName);

    /**
     * 验证名称的唯一性
     *
     * @param params 唯一性的参数信息
     * @return long
     */
    long checkNameUnique(MultiValueMap<String, String> params);


    /**
     * 验证名称的唯一性
     *
     * @param params 唯一性的参数信息
     * @return long
     */
    long checkCodeUnique(MultiValueMap<String, String> params);

    /**
     * 根据部门id获得部门信息
     *
     * @param departId ID
     * @return departCode 部门编码
     */
    String getDepartById(String departId);

    /**
     * 根据部门id获得部门信息
     *
     * @param departId ID
     * @return DepartNode 部门
     */
    DepartQo queryDepartById(String departId);

    /**
     * 获取组织树(全加载)
     *
     * @param departCode   部门编码
     * @param accessSubOrg 是否允许访问下级组织
     * @return List
     */
    List<DepartNode> departTree(String departCode, String accessSubOrg);

    /**
     * 获取用户区域树
     *
     * @param orgCode      组织编码
     * @param isDomain 是否区域管理员
     * @param paramMap 额外的过滤条件
     * @return List
     */
    List<DomainTreeNode> domainUserTree(String orgCode, boolean isDomain, Map<String, String> paramMap);

    /**
     * 根据ID获取部门信息
     *
     * @param id ID
     * @return 部门信息
     */
    DepartQo findById(String id);

    /**
     * 根据部门编码获取部门信息
     *
     * @param departCode 部门编码
     * @return 部门信息
     */
    DepartQo findByDepartCode(String departCode);

    DepartQo findByDepartByRouteCode(String routeCode);


    /**
     * 根据部门统一社会信息代码获取部门信息
     *
     * @param unifiedCode 统一社会信息代码
     * @return 部门信息
     */
    DepartQo findByUnifiedCode(String unifiedCode);

    /**
     * 根据当前部门获取管理域下部门
     *
     * @param departId 当前部门ID
     * @return List
     */
    List<String> getDepartIdsWithDomainByCurrent(String departId);

    /**
     * 根据当前部门获取管理域下部门
     *
     * @param departId 当前部门ID
     * @return List
     */
    List<DepartQo> getDepartWithDomain(String departId);

    /**
     * 根据父id查询部门id集
     * @param departId 父id
     * @param childLv 子集级别
     * @return
     */
    List<String> getDeptIdsWithPid(String departId, String childLv);

    /**
     * 根据当前部门获取管理域下机构部门
     *
     * @param departId 当前部门ID
     * @return List
     */
    List<String> getDepartIdsWithDomainById(String departId);

    /**
     * 获取管理域树
     *
     * @return 所有管理域树
     */
    TreeNode departDomainTree();

    /**
     * 根据组织名称查询组织ID
     *
     * @param departName 组织名称
     * @return 组织ID列表
     */
    List<String> queryDepartIdByName(String departName);

    /**
     * 根据部门编码查询当前及下级ID
     *
     * @param departId 部门ID
     * @return 部门ID列表
     */
    List<String> queryChildrenIdsById(String departId);

    /**
     * 查询所有可用，未删除的部门
     *
     * @return Map<String, String>
     */
    Map<String, String> queryAllDeparts();

    /**
     * 查询根部门id
     *
     * @return String
     */
    String getRootCode();

    /**
     * 根据用户id获取该用户所属部门的信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    SysDepart getDepartByUserId(String userId);

    /**
     * 根据用户id获取该用户所属部门的信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    DepartQo queryDepartByUserId(String userId);

    /**
     * 根据部门社会信用代码查询部门
     *
     * @param deptUnifiedCode 信用代码
     * @return 部门信息
     */
    DepartQo findByDeptUnifiedCode(String deptUnifiedCode);

    /**
     * 获得左侧组织树，只显示类型区域
     *
     * @return List<DepartNode>
     */
    List<DomainTreeNode> leftDomainTree();

    /**
     * 超级管理员分页查询信息
     *
     * @param predicate  查询条件
     * @param pageable   分页参数
     * @param parameters 查询参数
     * @return page
     */
    Page<DepartQo> searchPage(Predicate predicate, Pageable pageable, MultiValueMap<String, String> parameters);

    /**
     * 同步用户到子系统
     *
     * @param id 角色id
     */
    void syncSubsystem(String id);

    /**
     * 根据当前部门id 查询 所属区域code
     * 如果当前部门为 区域则返回对应code  如果当前部门为机构则返回该机构所属区域code
     *
     * @param departId 部门id
     * @return 区域code
     */
    String getDomainDepartCode(String departId);

    /**
     * 根据组织父级id 查询子集组织
     *
     * @param parentId   父级id
     * @param status     状态
     * @param departKind 组织类型
     * @return 部门节点集合
     */
    List<DepartNode> children(String parentId, String status, String departKind);

    /**
     * 根据用户所在部门id 查询
     *
     * @param departCode 部门编码
     * @param status     状态
     * @param departKind 组织类型
     * @return 部门节点集合
     */
    List<DepartNode> rootDepart(String departCode, String status, String departKind);

    /**
     * 根据组织类型查询集合
     *
     * @param parentId   父级id
     * @param departKind 组织类型
     * @param addSelf    是否包含父级id所对应的部门
     * @return 部门节点集合
     */
    List<DepartQo> queryDepartByKind(String parentId, String departKind, String addSelf);

    /**
     * 获取下级部门列表
     * @param region 上级部门id
     * @param normal 机构类型
     * @param level 机构等级
     * @param pageInfo 分页信息
     * @return 机构列表
     */
    Page<DepartQo> getSubDepartPage(String region, String normal, int level, Pageable pageInfo);

    /**
     * 获取同级部门列表
     * @param region 同级区域id
     * @param normal 机构类型
     * @param pageInfo 分页信息
     * @return 机构列表
     */
    Page<DepartQo> queryPageByRegion(String region, String normal, Pageable pageInfo);

    /**
     * 初始化统一社会信用代码映射行政区划代码
     */
    void unifiedCodeRegionId();

    /**
     *  查询组织树
     * @param departId 组织id
     * @param departCode 主旨编号
     * @param level 距离当前组织的层级 为正查询父级 为负查子级
     * @param ccf 是否包括当前组织
     * @return
     */
    List<DepartQo> searchDepartTree(String departId,String departCode,int level, boolean ccf);

    /**
     *  查询岗位组织树
     * @return
     */
    List<DepartQo> findPositionDepartTree();

    /**
     * 查询机构组织列表
     * @return
     */
    List<DepartQo> findNormalDepart(Map<String, String> param);

    void refreshAllRouteCode();

    /**
     * 获取所有岗位信息
     * @return
     * @param departId 部门id
     */
    List<SysDepart> findPosition(String departId);

    /**
     * 获取所有的子部门，不进行组织类型区分
     * @param departId 部门id
     * @return 返回
     */
    List<String> getChildDepartIdsById(String departId);

    /**
     * 根据部门名称，返回所有id
     * @param map 部门id
     * @return 返回
     */
    List<String> getDepartId(Map<String, String> map);
}
